package com.teacher.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.teacher.common.CommonResult;
import com.teacher.common.JwtTokenUtil;
import com.teacher.mapper.TermMapper;
import com.teacher.pojo.dto.login.LoginDto;
import com.teacher.pojo.dto.teacher.TeacherGetByDeptDto;
import com.teacher.pojo.dto.teacher.TeacherUpdateDto;
import com.teacher.pojo.entity.*;
import com.teacher.mapper.PerTeacherMapper;
import com.teacher.pojo.enums.PermissionType;
import com.teacher.pojo.json.PermissionList;
import com.teacher.pojo.json.RoleList;
import com.teacher.pojo.vo.teacher.TeacherGetVo;
import com.teacher.security.entity.permission.MenuReturnVo;
import com.teacher.security.entity.permission.Permission;
import com.teacher.security.entity.security.RedisUserInfo;
import com.teacher.security.service.IRedisService;
import com.teacher.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zfm
 * @since 2021-06-15
 */
@Service
public class PerTeacherServiceImpl extends ServiceImpl<PerTeacherMapper, PerTeacher> implements IPerTeacherService {

    @Value("${jwt.expiration}")
    private Long expiration;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private IRedisService iRedisService;

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Autowired
    private IRoleService iRoleService;

    @Autowired
    private IPermissionService iPermissionService;

    @Autowired
    private IDepartmentService iDepartmentService;

    @Autowired
    private IPerStudentService iPerStudentService;

    @Autowired
    private IGlobeConfigService iGlobeConfigService;

    @Autowired
    private TermMapper termMapper;

    /**
     * 根据部门查询教师信息
     *
     * @param dto
     * @return
     */
    @Override
    public CommonResult getByDepartmentId(TeacherGetByDeptDto dto) {
        IPage page = new Page(dto.getCurrentPage(), dto.getPageSize());

        IPage<TeacherGetVo> userReturnVoList = baseMapper.getUserPages(page, dto);

        for (TeacherGetVo record : userReturnVoList.getRecords()) {
            RoleList roleList = JSONUtil.toBean(record.getRoleInfo(), RoleList.class);
            if (roleList.getRoleList().size() == 0) {
                continue;
            }
            List<Role> roles = iRoleService.list(new QueryWrapper<Role>().lambda()
                    .select(Role::getName)
                    .in(BaseEntity::getId, roleList.getRoleList()));
            for (Role role : roles) {
                if (record.getRolesName() == null) {
                    record.setRolesName(new ArrayList<>());
                }
                record.getRolesName().add(role.getName());
            }
        }

        return CommonResult.success(userReturnVoList);

    }

    /**
     * 更新用户信息
     *
     * @param dto
     * @return
     */
    @Override
    public CommonResult updateInfo(TeacherUpdateDto dto) {
        PerTeacher perTeacher = new PerTeacher();
        BeanUtils.copyProperties(dto, perTeacher);

        RoleList roleList = new RoleList();
        if (roleList.getRoleList() == null) {
            roleList.setRoleList(new ArrayList<>());
        }
        for (Long aLong : dto.getRoleInfo()) {
            roleList.getRoleList().add(String.valueOf(aLong));
        }

        perTeacher.setRoleInfo(JSONUtil.toJsonStr(roleList));
        perTeacher.setUpperDept(dto.getDepartmentId() + "");

        if (baseMapper.update(perTeacher, new UpdateWrapper<PerTeacher>().lambda()
                .eq(PerTeacher::getTeacherKey, dto.getTeacherKey())) == 1) {
            // 更新accessPermit表
            PerTeacher perTeacher1 = baseMapper.selectOne(new QueryWrapper<PerTeacher>().lambda()
                    .eq(PerTeacher::getTeacherKey, dto.getTeacherKey()));

            String deptName = iDepartmentService.getById(dto.getDepartmentId()).getName();

            return CommonResult.success("更新成功");
        }
        return CommonResult.failed("更新失败");
    }

    /**
     * 登录
     *
     * @param dto
     * @return
     */
    @Override
    public CommonResult<ConcurrentMap<String, Object>> login(LoginDto dto) {

        ConcurrentMap<String, Object> concurrentMap = new ConcurrentHashMap<>();
        concurrentMap.put("isTeacher", false);
        concurrentMap.put("isStudent", false);
        PerTeacher perTeacher = baseMapper.selectOne(new QueryWrapper<PerTeacher>().lambda()
                .eq(PerTeacher::getTeacherKey, dto.getStaffNumber()));
        PerStudent perStudent = null;
        if (perTeacher == null) {
            perStudent = iPerStudentService.getOne(new QueryWrapper<PerStudent>().lambda()
                    .eq(PerStudent::getStudentKey, dto.getStaffNumber()).last("limit 1"));
            if (perStudent == null) {
                return CommonResult.failed("非法用户");
            }
        }

        RoleList roleList = new RoleList();
        List<Permission> permissionList = new ArrayList<>();
        String token = "";
        String username = "";
        String name = "";
        // 是否数据维护
        String isMaintenance = iGlobeConfigService.getById(1).getName();
        List<String> permissionValue = new ArrayList<>();
        if (perTeacher != null) {
            roleList = JSONUtil.toBean(perTeacher.getRoleInfo(), RoleList.class);
            token = jwtTokenUtil.generateToken(perTeacher.getTeacherKey());
            username = perTeacher.getTeacherKey();
            name = perTeacher.getName();
            if (perTeacher.getLastLogin() == null) {
                concurrentMap.put("lastLogin", "首次登陆");
            } else {
                concurrentMap.put("lastLogin", DateUtil.format(perTeacher.getLastLogin(), "yyyy-MM-dd HH:mm:ss"));
            }

            perTeacher.setLastLogin(new Date());
            this.updateById(perTeacher);
            concurrentMap.put("isTeacher", true);


        } else {
            List<String> studentRole = new ArrayList<>();
            studentRole.add("1424271039948562434");
            roleList.setRoleList(studentRole);
            token = jwtTokenUtil.generateToken(perStudent.getStudentKey());
            username = perStudent.getStudentKey();
            name = perStudent.getName();

            if (perStudent.getLastLogin() == null) {
                concurrentMap.put("lastLogin", "首次登陆");
            } else {
                concurrentMap.put("lastLogin", DateUtil.format(perStudent.getLastLogin(), "yyyy-MM-dd HH:mm:ss"));
            }


            perStudent.setLastLogin(new Date());
            iPerStudentService.updateById(perStudent);
            concurrentMap.put("isStudent", true);
        }

        boolean isAdmin = false;

        if (roleList.getRoleList().contains("1339929040605925377")) {
            isAdmin = true;
        }

        if (roleList.getRoleList().size() != 0) {
            List<Role> roles = iRoleService.list(new QueryWrapper<Role>().lambda()
                    .in(BaseEntity::getId, roleList.getRoleList()));
            for (Role role : roles) {
                PermissionList permissions = JSONUtil.toBean(role.getPermission(), PermissionList.class);
                List<Permission> getPermission = iPermissionService.list(new QueryWrapper<Permission>().lambda()
                        .in(Permission::getId, permissions.getPermissionList()).orderByDesc(Permission::getSort));
                if (isAdmin) {
                    permissionList.addAll(getPermission);
                    continue;
                }
                // 是数据维护
                if (getPermission.size() > 0) {
                    for (Permission permission : getPermission) {
                        if (isMaintenance.equals("是")) {
                            // 是数据维护
                            if (permission.getIsMaintenance()) {
                                permissionList.add(permission);
                            }
                        } else {
                            // 不是数据维护
                            if (!permission.getIsMaintenance()) {
                                permissionList.add(permission);
                            }
                        }
                    }
                }
            }
            // 去重
            permissionList = permissionList.stream().distinct().collect(Collectors.toList());
            // 获取权限码
            for (Permission permission : permissionList) {
                if (permission.getType().equals(PermissionType.BUTTON.getCode())) {
                    permissionValue.add(permission.getPermissionValue());
                }
            }
        }
        RedisUserInfo redisUserInfo = new RedisUserInfo();

        redisUserInfo.setToken(token);

        redisUserInfo.setPermissionValue(permissionValue);

        redisUserInfo.setAllMenu(permissionList);

        iRedisService.set(username, JSONUtil.toJsonStr(redisUserInfo));
        iRedisService.expire(username, expiration);
        concurrentMap.put("token", token);
        concurrentMap.put("permissionValueList", permissionValue);
        concurrentMap.put("name", name);
        concurrentMap.put("username", username);
        Term term = termMapper.selectOne(new QueryWrapper<Term>().lambda()
                .eq(Term::getIsCurrent, true));
        if (term != null) {
            concurrentMap.put("currentTerm", term.getYear() + "-" + term.getTerm());
        }
        return CommonResult.success(concurrentMap);
    }

    /**
     * 获取用户菜单
     *
     * @return
     */
    @Override
    public CommonResult getMenu() {
        RedisUserInfo redisUserInfo = JSONUtil.toBean(
                iRedisService.get(jwtTokenUtil.getUsernameByRequest(httpServletRequest)), RedisUserInfo.class);
        List<Permission> permissionList = redisUserInfo.getAllMenu();
        // menu
        List<MenuReturnVo> menuReturnVoList = new ArrayList<>();
        List<MenuReturnVo> oriMenuList = new ArrayList<>();
        for (Permission permission : permissionList) {
            MenuReturnVo menuReturnVo = new MenuReturnVo();
            BeanUtils.copyProperties(permission, menuReturnVo);
            menuReturnVo.setLabel(permission.getName());
            oriMenuList.add(menuReturnVo);
        }
        for (MenuReturnVo menuReturnVo : oriMenuList) {
            if (menuReturnVo.getType().equals(PermissionType.BUTTON.getCode())) {
                continue;
            }
            if (menuReturnVo.getParentId() == 0) {
                menuReturnVoList.add(menuReturnVo);
                continue;
            }
            for (MenuReturnVo returnVo : oriMenuList) {
                if (menuReturnVo.getParentId().equals(returnVo.getId())) {
                    if (returnVo.getChildren() == null) {
                        returnVo.setChildren(new ArrayList<>());
                    }
                    returnVo.getChildren().add(menuReturnVo);
                }
            }
        }
        return CommonResult.success(menuReturnVoList);
    }

    /**
     * 用户登出
     *
     * @return
     */
    @Override
    public CommonResult logout() {
        iRedisService.remove(jwtTokenUtil.getUsernameByRequest(httpServletRequest));
        return CommonResult.success("退出成功");
    }
}
